"""
Pydantic 模型定义

定义了项目中所有的数据模型，包括：
- 用户相关模型
- 认证相关模型
- 响应模型
"""

from pydantic import BaseModel, EmailStr, Field, validator
from typing import Optional
from datetime import datetime


# ========== 用户基础模型 ==========


class UserBase(BaseModel):
    """用户基础模型"""

    username: str = Field(
        ..., min_length=3, max_length=20, description="用户名，3-20个字符"
    )
    email: EmailStr = Field(..., description="电子邮箱")


# ========== 用户注册模型 ==========


class UserRegister(UserBase):
    """用户注册输入模型"""

    password: str = Field(..., min_length=8, max_length=50, description="密码，至少8个字符")
    full_name: Optional[str] = Field(None, max_length=50, description="全名")
    age: Optional[int] = Field(None, ge=0, le=150, description="年龄")

    @validator("username")
    def username_alphanumeric(cls, v):
        """验证用户名只包含字母、数字和下划线"""
        if not v.replace("_", "").isalnum():
            raise ValueError("用户名只能包含字母、数字和下划线")
        return v

    @validator("password")
    def password_strength(cls, v):
        """验证密码强度"""
        if not any(c.isupper() for c in v):
            raise ValueError("密码必须包含至少一个大写字母")
        if not any(c.islower() for c in v):
            raise ValueError("密码必须包含至少一个小写字母")
        if not any(c.isdigit() for c in v):
            raise ValueError("密码必须包含至少一个数字")
        return v

    class Config:
        json_schema_extra = {
            "example": {
                "username": "alice",
                "email": "alice@example.com",
                "password": "Alice123",
                "full_name": "Alice Wang",
                "age": 25,
            }
        }


# ========== 用户登录模型 ==========


class UserLogin(BaseModel):
    """用户登录输入模型"""

    username: str = Field(..., description="用户名")
    password: str = Field(..., description="密码")

    class Config:
        json_schema_extra = {
            "example": {"username": "alice", "password": "Alice123"}
        }


# ========== 用户更新模型 ==========


class UserUpdate(BaseModel):
    """用户更新输入模型（所有字段可选）"""

    email: Optional[EmailStr] = None
    full_name: Optional[str] = Field(None, max_length=50)
    age: Optional[int] = Field(None, ge=0, le=150)

    class Config:
        json_schema_extra = {
            "example": {"email": "newemail@example.com", "full_name": "Alice Wang", "age": 26}
        }


# ========== 数据库用户模型 ==========


class UserInDB(UserBase):
    """数据库中的用户模型（包含所有字段）"""

    id: int
    hashed_password: str
    full_name: Optional[str] = None
    age: Optional[int] = None
    role: str = "user"  # user / admin
    is_active: bool = True
    created_at: datetime
    updated_at: datetime


# ========== 用户响应模型 ==========


class UserResponse(UserBase):
    """用户响应模型（不包含密码）"""

    id: int
    full_name: Optional[str] = None
    age: Optional[int] = None
    role: str
    is_active: bool
    created_at: datetime

    class Config:
        from_attributes = True
        json_schema_extra = {
            "example": {
                "id": 1,
                "username": "alice",
                "email": "alice@example.com",
                "full_name": "Alice Wang",
                "age": 25,
                "role": "user",
                "is_active": True,
                "created_at": "2024-01-01T00:00:00",
            }
        }


# ========== 登录响应模型 ==========


class LoginResponse(BaseModel):
    """登录成功响应模型"""

    access_token: str = Field(..., description="访问令牌")
    token_type: str = Field(default="bearer", description="令牌类型")
    user: UserResponse = Field(..., description="用户信息")

    class Config:
        json_schema_extra = {
            "example": {
                "access_token": "token_alice",
                "token_type": "bearer",
                "user": {
                    "id": 1,
                    "username": "alice",
                    "email": "alice@example.com",
                    "role": "user",
                    "is_active": True,
                },
            }
        }


# ========== 角色更新模型 ==========


class RoleUpdate(BaseModel):
    """角色更新模型"""

    role: str = Field(..., pattern="^(user|admin)$", description="用户角色: user 或 admin")

    class Config:
        json_schema_extra = {"example": {"role": "admin"}}


# ========== 统计信息模型 ==========


class SystemStats(BaseModel):
    """系统统计信息模型"""

    total_users: int
    active_users: int
    inactive_users: int
    admin_users: int
    regular_users: int

    class Config:
        json_schema_extra = {
            "example": {
                "total_users": 10,
                "active_users": 8,
                "inactive_users": 2,
                "admin_users": 1,
                "regular_users": 9,
            }
        }

